/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"
#include ".\ScanMethodNetBios.h"

#include "NetBios.h"

//--------------------------------------------------------------------

ScanMethodNetBios::ScanMethodNetBios(void) : ScanMethod()
{
	myType = __wmtNetBios;
}

ScanMethodNetBios::~ScanMethodNetBios(void)
{
}

//--------------------------------------------------------------------

int ScanMethodNetBios::InternalInit(void)
{
	FillRandomBuffer();
	
	if(workPhase==__wptDiscovery) return MSR_ERR_OK;
	if(workPhase==__wptScan)      return MSR_ERR_OK;

	return MSR_ERR_PHASE;
}

int ScanMethodNetBios::InternalExecute(void)
{
	MMachineInfo* mmi;
	BYTE macBuff[6];
	CString str;
	NetBios nb;
	int retVal;
	int i, nbCnt;

	if(addrList==NULL) return MSR_ERR_PARAMETER;

	ScanPair sp;
	while(GetNextPair(&sp, __sptIpOnly) && !stopStopStop){
		if(sp.addr!=NULL){
			if(!sp.addr->addrIP.IsEmpty()){
				if(workPhase==__wptDiscovery && sp.addr->alive){
					// it's the discovery phase and a previous discovery method has found it already
					// so skip this one
				}
				else{
					if(config->xMinDelay>0){
						if(lastScanTime!=0){
							waitDone = false;
							while(!waitDone){
								CheckResponses();
								SleepEx(1, TRUE);
								scanTime = GetTickCount();
								scanTime = ComputeDeltaTime(lastScanTime, scanTime);
								if(scanTime>=config->xMinDelay)
									waitDone = true;
							}
						}
						lastScanTime = GetTickCount();
					}

					nb.SetAddress(sp.addr->addrIP.GetS());
					packSent++;
					retVal = nb.GetNetBiosInfo(&macBuff[0]);
					if(retVal>=0){
						// NB succeded
						if(workPhase==__wptDiscovery){
							sp.addr->alive = true;
							for(i=0; i<6; i++)
								sp.addr->addrMACnb.addr[i] = macBuff[i];
						}
						else{
							mmi = FindMachineByIp(sp.addr->addrIP.GetD());
							if(mmi!=NULL){
								mmi->address.alive = true;
								for(i=0; i<6; i++)
									mmi->address.addrMACnb.addr[i] = macBuff[i];

								nbCnt = retVal;
								if(nbCnt>MAX_NB_NAMES)
									nbCnt = MAX_NB_NAMES;
								mmi->nbNamesCnt = nbCnt;
								for(i=0; i<nbCnt; i++)
									mmi->nbNames[i] = nb.GetNBName(i);

								if(nb.EnumerateShares()){
									nbCnt = nb.shareInfoList.GetSize();
									for(i=0; i<nbCnt; i++)
										mmi->AddShareInfoNoDuplicates(nb.shareInfoList.GetByIdx(i));
								}
							}
						}
					}

					if((packSent % notifNetBios) == 0 && packSent>0)
						if(hWnd!=NULL)
							PostMessage(hWnd, CHS_MSG_PACKETS_SENT, 0, (LPARAM)packSent);
				}
			}
		}
	}

	return MSR_ERR_OK;
}

//--------------------------------------------------------------------

void ScanMethodNetBios::ComputeRandomValues(void)
{
	// nothing to do
}

//--------------------------------------------------------------------
